<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>AI 聊天室 - 刘文锋</title>
    <style>
        body {
            font-family: 'Arial', sans-serif;
            display: flex;
            flex-direction: column;
            align-items: center;
            margin: 0;
            padding: 20px;
            background-color: #f0f2f5; /* Fallback background color */
            /* 请将下面的URL替换为您选择的胡桃图片URL */
            background-image: url('http://localhost:8080/images/hutao.jpeg'); /* 示例胡桃图片URL */
            background-size: cover;
            background-position: center;
            background-attachment: fixed;
            min-height: 100vh;
        }
        .top-left-name {
            position: fixed; /* 或者 absolute，取决于滚动行为需求 */
            top: 15px;
            left: 15px;
            font-size: 20px;
            font-weight: bold;
            color: #fff; /* 白色字体，确保在背景图上可见 */
            background-color: rgba(0, 0, 0, 0.5); /* 半透明黑色背景，增加可读性 */
            padding: 8px 15px;
            border-radius: 5px;
            z-index: 1000; /* 确保在最上层 */
        }
        .container {
            background-color: rgba(255, 255, 255, 0.6); /* 略微透明的白色背景 */
            padding: 25px;
            border-radius: 10px;
            box-shadow: 0 4px 15px rgba(0,0,0,0.2);
            width: 85%;
            max-width: 750px;
            margin-top: 60px; /* 为顶部的名字留出空间 */
        }
        h2 {
            color: #2c3e50;
            text-align: center;
            border-bottom: 2px solid #3498db;
            padding-bottom: 10px;
            margin-bottom: 25px;
        }
        .chat-section {
            margin-bottom: 25px;
            padding: 20px;
            border: 1px solid #bdc3c7;
            border-radius: 8px;
            background-color: #ffffff;
        }
        .chat-section h3 {
            color: #3498db;
            margin-top: 0;
        }
        label {
            display: block;
            margin-bottom: 8px;
            color: #34495e;
            font-weight: bold;
        }
        input[type="text"],
        input[type="number"],
        textarea {
            width: calc(100% - 24px); /* 减去padding和border */
            padding: 12px;
            margin-bottom: 12px;
            border: 1px solid #ccc;
            border-radius: 5px;
            box-sizing: border-box; /* 确保padding和border不增加总宽度 */
            font-size: 1em;
        }
        textarea {
            min-height: 80px;
            resize: vertical;
        }
        button {
            padding: 12px 18px;
            background-color: #3498db;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            margin-right: 8px;
            font-size: 1em;
            transition: background-color 0.3s ease;
        }
        button:hover {
            background-color: #2980b9;
        }
        .response-area {
            margin-top: 15px;
            padding: 15px;
            border: 1px solid #ecf0f1;
            background-color: #f8f9fa;
            min-height: 60px;
            border-radius: 5px;
            white-space: pre-wrap;
            word-wrap: break-word;
            font-family: 'Courier New', Courier, monospace;
            font-size: 0.95em;
            line-height: 1.6;
        }

        .comments-section {
            width: 85%;
            max-width: 750px;
            margin-top: 20px;
            padding: 20px;
            background-color: rgba(255, 255, 255, 0.6);
            border-radius: 10px;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
        }

        .comments-section h3 {
            color: #2c3e50;
            margin-bottom: 15px;
        }

        #comments-list {
            margin-bottom: 20px;
            padding: 10px;
            border: 1px solid #ccc;
            border-radius: 5px;
            background-color: #fff;
        }

        .comment-form textarea {
            width: calc(100% - 24px);
            padding: 12px;
            margin-bottom: 12px;
            border: 1px solid #ccc;
            border-radius: 5px;
            box-sizing: border-box;
            font-size: 1em;
            min-height: 80px;
            resize: vertical;
        }

        .comment-form button {
            padding: 12px 18px;
            background-color: #3498db;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 1em;
            transition: background-color 0.3s ease;
        }

        .comment-form button:hover {
            background-color: #2980b9;
        }
    </style>
</head>
<body>

<div class="top-left-name">刘文锋的AI聊天室</div>


<div class="container">
    <h2>AI 聊天交互</h2>

    <!-- 普通聊天 -->
    <div class="chat-section">
        <h3>普通非流式聊天</h3>
        <label for="chat-message">消息:</label>
        <input type="text" id="chat-message" value="你是谁">
        <button onclick="sendMessage('/ai/chat', 'chat-message', 'chat-response')">发送</button>
        <div class="response-area" id="chat-response"></div>
    </div>

    <!-- 普通流式聊天 -->
    <div class="chat-section">
        <h3>普通流式聊天</h3>
        <label for="stream-message">消息:</label>
        <input type="text" id="stream-message" value="给我讲个关于宇宙的笑话">
        <button onclick="sendStreamMessage('/ai/stream', 'stream-message', 'stream-response')">发送 (流式)</button>
        <div class="response-area" id="stream-response"></div>
    </div>

    <!-- 带记忆的流式聊天 -->
    <div class="chat-section">
        <h3>带记忆且具备RAG检索的流式聊天</h3>
        <label for="memory-stream-message">消息:</label>
        <input type="text" id="memory-stream-message" value="我喜欢蓝色">
        <button onclick="sendStreamMessage('/ai/memory_stream_chat', 'memory-stream-message', 'memory-stream-response')">发送 (流式)</button>
        <br><label for="memory-stream-message-2">后续消息 (测试记忆):</label>
        <input type="text" id="memory-stream-message-2" value="我最喜欢的颜色是什么？">
        <button onclick="sendStreamMessage('/ai/memory_stream_chat', 'memory-stream-message-2', 'memory-stream-response')">再次发送 (流式)</button>
        <div class="response-area" id="memory-stream-response"></div>
    </div>

    <!-- 带用户ID的记忆聊天 -->
    <div class="chat-section">
        <h3>区分用户的流式聊天</h3>
        <label for="memory-id-message">消息:</label>
        <input type="text" id="memory-id-message" value="我的幸运数字是7">
        <label for="user-id">用户ID:</label>
        <input type="number" id="user-id" value="123">
        <button onclick="sendMessageWithUserId('/ai/memoryId_chat', 'memory-id-message', 'user-id', 'memory-id-response')">发送</button>
        <br><label for="memory-id-message-2">后续消息 (测试记忆):</label>
        <input type="text" id="memory-id-message-2" value="我的幸运数字是多少？">
        <button onclick="sendMessageWithUserId('/ai/memoryId_chat', 'memory-id-message-2', 'user-id', 'memory-id-response')">再次发送</button>
        <div class="response-area" id="memory-id-response"></div>
    </div>

    <!-- RAG 接口 -->
    <div class="chat-section">
        <h3>RAG 文本处理</h3>
        <label for="rag-message">文本内容 (用于向量化):</label>
        <textarea id="rag-message" placeholder="在此输入要处理的文本...">这是一个示例文本，用于RAG处理。</textarea>
        <button onclick="sendRagMessage('/rag/txt', 'rag-message', 'rag-response')">发送进行RAG处理</button>
        <div class="response-area" id="rag-response"></div>
    </div>

    <!-- RAG Flow 流式聊天 -->
    <div class="chat-section">
        <h3>RAG Flow 流式聊天</h3>
        <label for="ragflow-message">消息:</label>
        <input type="text" id="ragflow-message" value="什么是量子计算？">
        <button onclick="sendRagFlowMessage()">发送 (流式)</button>
        <div class="response-area" id="ragflow-response"></div>
    </div>

    <!-- 测试模型维度接口 -->
    <div class="chat-section">
        <h3>测试嵌入模型维度</h3>
        <button onclick="callTestDim('/rag/test-dim', 'test-dim-response')">获取模型维度</button>
        <div class="response-area" id="test-dim-response"></div>
    </div>

</div>

<!-- 新增评论区域 -->
<div class="comments-section">
    <h3>用户评论</h3>
    <div id="comments-list">
        <!-- 评论列表 -->
    </div>
    <div class="comment-form">
        <label for="comment-input">发表评论:</label>
        <textarea id="comment-input" placeholder="在这里输入你的评论..."></textarea>
        <button onclick="submitComment()">提交</button>
    </div>
</div>

<script>
    const API_BASE_URL = 'http://localhost:8080'; // 定义后端API的基础URL

    async function sendMessage(endpoint, messageId, responseId) {
        const messageInput = document.getElementById(messageId);
        const message = messageInput.value;
        const responseArea = document.getElementById(responseId);
        responseArea.textContent = '正在请求...';

        try {
            const response = await fetch(`${API_BASE_URL}${endpoint}?message=${encodeURIComponent(message)}`);
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status} ${await response.text()}`);
            }
            const data = await response.text();
            responseArea.textContent = data;
        } catch (error) {
            console.error('请求失败:', error);
            responseArea.textContent = '请求失败: ' + error.message;
        }
    }

    async function sendMessageWithUserId(endpoint, messageId, userIdId, responseId) {
        const messageInput = document.getElementById(messageId);
        const message = messageInput.value;
        const userIdInput = document.getElementById(userIdId);
        const userId = userIdInput.value;
        const responseArea = document.getElementById(responseId);
        responseArea.textContent = '正在请求...';

        if (!userId) {
            responseArea.textContent = '请输入用户ID。';
            return;
        }

        try {
            const response = await fetch(`${API_BASE_URL}${endpoint}?message=${encodeURIComponent(message)}&userId=${encodeURIComponent(userId)}`);
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status} ${await response.text()}`);
            }
            const data = await response.text();
            responseArea.textContent = data;
        } catch (error) {
            console.error('请求失败:', error);
            responseArea.textContent = '请求失败: ' + error.message;
        }
    }

    function sendStreamMessage(endpoint, messageId, responseId) {
        const messageInput = document.getElementById(messageId);
        const message = messageInput.value;
        const responseArea = document.getElementById(responseId);
        responseArea.textContent = ''; // 清空之前的流式响应
        let fullResponse = '';

        const eventSource = new EventSource(`${API_BASE_URL}${endpoint}?message=${encodeURIComponent(message)}`);

        eventSource.onopen = function() {
            responseArea.textContent = '流连接已建立...\n';
        };

        eventSource.onmessage = function(event) {
            fullResponse += event.data;
            responseArea.textContent = fullResponse;
        };

        eventSource.onerror = function(error) {
            console.error('EventSource 失败:', error);
            responseArea.textContent += '\n流连接错误或关闭。';
            eventSource.close();
        };
    }

    async function sendRagMessage(endpoint, messageId, responseId) {
        const messageTextarea = document.getElementById(messageId);
        const messageContent = messageTextarea.value;
        const responseArea = document.getElementById(responseId);
        responseArea.textContent = '正在请求...';

        // The RAG endpoint expects a TextSegment, which is essentially a string.
        // We'll send it as a query parameter named 'message' as per typical Spring @RequestParam behavior for simple types.
        // If the backend expects a JSON body like {"text":"..."}, this needs to be adjusted to a POST request with a JSON body.
        // Assuming @RequestParam TextSegment message will take the string directly for its 'text' field or has a converter.
        try {
            const response = await fetch(`${API_BASE_URL}${endpoint}?message=${encodeURIComponent(messageContent)}`);
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status} ${await response.text()}`);
            }
            const data = await response.text();
            responseArea.textContent = data;
        } catch (error) {
            console.error('RAG 请求失败:', error);
            responseArea.textContent = 'RAG 请求失败: ' + error.message;
        }
    }

    async function callTestDim(endpoint, responseId) {
        const responseArea = document.getElementById(responseId);
        responseArea.textContent = '正在请求...';

        try {
            const response = await fetch(`${API_BASE_URL}${endpoint}`);
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status} ${await response.text()}`);
            }
            const data = await response.text();
            responseArea.textContent = `模型维度: ${data}`;
        } catch (error) {
            console.error('测试维度请求失败:', error);
            responseArea.textContent = '测试维度请求失败: ' + error.message;
        }
    }


    // 获取评论列表
    async function fetchComments() {
        const response = await fetch(`${API_BASE_URL}/comment/list`);
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        return await response.json();
    }

    // 提交评论
    async function submitComment() {
        const commentInput = document.getElementById('comment-input');
        const comment = commentInput.value.trim();

        if (comment === '') {
            alert('请输入评论内容！');
            return;
        }

        const response = await fetch(`${API_BASE_URL}/comment/add`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({ content: comment })
        });

        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }

        // 清空输入框
        commentInput.value = '';

        // 重新加载评论列表
        loadComments();
    }

    // 加载评论列表
    async function loadComments() {
        try {
            const comments = await fetchComments();
            const commentsList = document.getElementById('comments-list');
            commentsList.innerHTML = ''; // 清空之前的评论

            comments.forEach(comment => {
                const commentElement = document.createElement('div');
                commentElement.className = 'comment';
                commentElement.innerHTML = `                <strong>${comment.user}:</strong> ${comment.content}            `;
                commentsList.appendChild(commentElement);
            });
        } catch (error) {
            console.error('获取评论失败:', error);
        }
    }
    function sendRagFlowMessage() {
        const messageInput = document.getElementById("ragflow-message");
        const message = messageInput.value.trim();
        const responseArea = document.getElementById("ragflow-response");
        let fullResponse = '';

        if (!message) {
            responseArea.textContent = '请输入问题内容。';
            return;
        }

        const url = `${API_BASE_URL}/api/v1/ragFlow`;

        // 构造请求体参数（由于 SseEmitter 不支持 POST 请求体，这里改用查询参数）
        const params = new URLSearchParams({
            question: message,
            stream: true,
            session_id: "4315d36f925746cfa97595f3a6871849"
        });

        const eventSource = new EventSource(`${url}?${params}`);

        eventSource.onopen = function () {
            console.log("SSE 连接已建立");
            responseArea.textContent = '流连接已建立...\n';
        };

        eventSource.onmessage = function (event) {
            fullResponse += event.data;
            responseArea.textContent = fullResponse;
        };

        eventSource.onerror = function (error) {
            console.error("SSE 出错，准备重连...", error);
            responseArea.textContent += '\n连接中断，正在尝试重新连接...\n';

            setTimeout(() => {
                eventSource.close();
                sendRagFlowMessage(); // 自动重连
            }, 5000);
        };
    }

    // 页面加载时调用
    document.addEventListener('DOMContentLoaded', loadComments);

</script>
</body>
</html>
